/*****************************************************************************/
// This file is part of Hikari3D.
// 
// Hikari3D is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// 
// Hikari3D is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
//
// Copyright 2008 Sebastian Pick
/*****************************************************************************/

#ifndef __MATERIALOBJECT_H
#define __MATERIALOBJECT_H

// === Defines ============================================================= //



// === Includes ============================================================ //
#include <string>

using namespace std;


// === Class Declaration =================================================== //
class CMaterialObject
{
public:
	// --- Structs --------------------------------------------------------- //
	struct sCOLOR
	{
		sCOLOR(float fR = 1.0f, float fG = 1.0f, float fB = 1.0f, float fA = 1.0f)
		{
			_fRed	= fR;
			_fGreen	= fG;
			_fBlue	= fB;
			_fAlpha	= fA;
		}

		float _fRed;
		float _fGreen;
		float _fBlue;
		float _fAlpha;
	};

	// --- Con-/Destructor ------------------------------------------------- //
	//! Default constructor.
	inline CMaterialObject();


	//! Default destructor.
	~CMaterialObject() {}


	// --- Accessors ------------------------------------------------------- //
	// ------------------------------------------------- //
	//! This function is to set the ambient color.
	/*!
		\param sAmbCol The ambient color of the material.

		NOTE: The default color is (1.0f, 1.0f, 1.0f, 1.0f).
			  Each component has to be in the range [0.0f, 1.0f].
			  Values out of this range will be clamped!
	 */
	inline void setAmbientColor(sCOLOR sAmbCol);

	//! This function is to retrieve/get the ambient color.
	/*!
		\return Returns structure containing the color.
	 */
	inline sCOLOR getAmbientColor() const;


	// ------------------------------------------------- //
	//! This function is to set the diffuse color.
	/*!
		\param sDiffCol The diffuse color of the material.

		NOTE: The default color is (1.0f, 1.0f, 1.0f, 1.0f).
			  Each component has to be in the range [0.0f, 1.0f].
			  Values out of this range will be clamped!
	 */
	inline void setDiffuseColor(sCOLOR sDiffCol);

	//! This function is to retrieve/get the diffuse color.
	/*!
		\return Returns structure containing the color.
	 */
	inline sCOLOR getDiffuseColor() const;


	// ------------------------------------------------- //
	//! This function is to set the specular color.
	/*!
		\param sSpecCol The specular color of the material.

		NOTE: The default color is (1.0f, 1.0f, 1.0f, 1.0f).
			  Each component has to be in the range [0.0f, 1.0f].
			  Values out of this range will be clamped!
	 */
	inline void setSpecularColor(sCOLOR sSpecCol);

	//! This function is to retrieve/get the specular color.
	/*!
		\return Returns structure containing the color.
	 */
	inline sCOLOR getSpecularColor() const;


	// ------------------------------------------------- //
	//! This function is to set the emissive color.
	/*!
		\param sEmiCol The emissive color of the material.

		NOTE: The default color is (1.0f, 1.0f, 1.0f, 1.0f).
			  Each component has to be in the range [0.0f, 1.0f].
			  Values out of this range will be clamped!
	 */
	inline void setEmissiveColor(sCOLOR sEmiCol);

	//! This function is to retrieve/get the emissive color.
	/*!
		\return Returns structure containing the color.
	 */
	inline sCOLOR getEmissiveColor() const;


	// ------------------------------------------------- //
	//! This function is to set the specular power/shininess.
	/*!
		\param fSpecPow The specular power/shininess.

		NOTE: The default value is 0.0f.
			  Must be positive. Negative values will be clamped to 0.0f!
	 */
	inline void setSpecularPower(float fSpecPow);

	//! This function is to retrieve/get the ambient color.
	/*!
		\return Returns structure containing the color.
	 */
	inline float getSpecularPower() const;

protected:

private:
	// --- Helper Functions ------------------------------------------------ //
	inline void clampColor(sCOLOR &sCol) const;


	// --- Member Variables ------------------------------------------------ //
	sCOLOR		_sAmbientColor,
				_sDiffuseColor,
				_sSpecularColor,
				_sEmissiveColor;

	float		_fSpecularPower;

};


// === Inline Functions ==================================================== //
// --- Constructor --------------------------------------------------------- //
inline CMaterialObject::CMaterialObject() 
	: _fSpecularPower(0.0f)
{

}


// --- Accessors ----------------------------------------------------------- //
inline void CMaterialObject::setAmbientColor(sCOLOR sAmbCol)
{
	this->clampColor(sAmbCol);

	_sAmbientColor = sAmbCol;
}

inline CMaterialObject::sCOLOR CMaterialObject::getAmbientColor() const
{
	return _sAmbientColor;
}


inline void CMaterialObject::setDiffuseColor(sCOLOR sDiffCol)
{
	this->clampColor(sDiffCol);

	_sDiffuseColor = sDiffCol;
}

inline CMaterialObject::sCOLOR CMaterialObject::getDiffuseColor() const
{
	return _sDiffuseColor;
}


inline void CMaterialObject::setSpecularColor(sCOLOR sSpecCol)
{
	this->clampColor(sSpecCol);

	_sSpecularColor = sSpecCol;
}

inline CMaterialObject::sCOLOR CMaterialObject::getSpecularColor() const
{
	return _sSpecularColor;
}


inline void CMaterialObject::setEmissiveColor(sCOLOR sEmiCol)
{
	this->clampColor(sEmiCol);

	_sEmissiveColor = sEmiCol;
}

inline CMaterialObject::sCOLOR CMaterialObject::getEmissiveColor() const
{
	return _sEmissiveColor;
}


inline void CMaterialObject::setSpecularPower(float fSpecPow)
{
	fSpecPow = fSpecPow < 0.0f ? 0.0f : fSpecPow;

	_fSpecularPower = fSpecPow;
}

inline float CMaterialObject::getSpecularPower() const
{
	return _fSpecularPower;
}

// --- Helper Functions ---------------------------------------------------- //
inline void CMaterialObject::clampColor(CMaterialObject::sCOLOR &sCol) const
{
	sCol._fRed = sCol._fRed < 0.0f ? 0.0f : sCol._fRed;
	sCol._fRed = sCol._fRed > 1.0f ? 1.0f : sCol._fRed;

	sCol._fGreen = sCol._fGreen < 0.0f ? 0.0f : sCol._fGreen;
	sCol._fGreen = sCol._fGreen > 1.0f ? 1.0f : sCol._fGreen;

	sCol._fBlue = sCol._fBlue < 0.0f ? 0.0f : sCol._fBlue;
	sCol._fBlue = sCol._fBlue > 1.0f ? 1.0f : sCol._fBlue;

	sCol._fAlpha = sCol._fAlpha < 0.0f ? 0.0f : sCol._fAlpha;
	sCol._fAlpha = sCol._fAlpha > 1.0f ? 1.0f : sCol._fAlpha;
}



#endif // __MATERIALOBJECT_H

// EOF
